BlurKit Release v1.1.1

Mon Jan 21 2019

Wow that’s a big logo

Today we’ve release v1.1.1, the latest release of BlurKit. It brings some small changes to help improve compatibility across devices.

Here’s the short list of changes, you can see entire pull request here.

Build and Gradle

  • Lower minimum SDK version from 21 to 17
  • Update Gradle to 3.3.0
  • Update Gradle wrapper to 4.10.1

As always, if you encounter any issues or have particular feature requests open a ticket on GitHub. Thanks for reading!


BlurKit Release v1.1.1 was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

An Open Source Community: How We Came To Use Spectrum

Fri Jan 18 2019

CameraKit is a robust open-source platform for quickly adding camera functionality to your android applications.

At CameraKit we strive to empower our community to not only expand CameraKit usage, but build a better product along the way. We’ve discovered a few tactics for accomplishing our goal: be available and responsive, open to feedback and build the CameraKit our community wants.

We had the vision, now we needed the tool.

The First — GitHub.

CameraKit started on GitHub. GitHub is a platform to house code, track changes and post issues. Posting issues it the main method one can interact with other developers on GitHub.

Starting out, we didn’t have a need for lengthy communication. We had a small following of developers looking to use CameraKit and help in its development.

As CameraKit grew, our GitHub page was attracting a wider audience. We noticed our issue page filling up with all sorts of questions. From a developer creating his or her first Android application, or a seasoned Android expert looking into the intricacies of our library. We didn’t have a good way of separating these two styles of questions and ended up with a backlog of issues.

In order to keep GitHub project development focused, we needed another solution.

Pros:

  1. Automatically set-up with our codebase hosting
  2. Good for software development related issues

Cons:

  1. Bugs and features mixed together with simpler questions.
  2. Difficult notification management

The Second — Slack.

Our team used Slack internally. When we wanted another place for communication and questions, it seemed like the natural first choice. Slack is primarily a tool for well defined teams, but decided to give it a try in our community use case. We created a public channel and had people join.

Slack worked well at a small scale for CameraKit. People were able to ask questions and get quick responses. We posted updates and new feature ideas, and were able to get feedback right in slack. The chats had much more of a discussion feel, where people could get help or talk about their applications and camera needs.

However, slack is inherently built for teams and not for large groups of people. There is a bit of a barrier to entry with using Slack for this type of communication. One has to sign up through the 3rd party tool by link only, and download the client. Because of this link only invite, our group was not easy to find by searching alone. Slack is also not indexed online, so finding questions that someone’s asked before was not possible.

Pros:

  1. Faster communication than GitHub
  2. More discussion focused than GitHub

Cons:

  1. Hard for people to join
  2. Poor member management
  3. Not indexed by Google for repeat questions

The Third — Spectrum.Chat

After searching for another tool to host informal CameraKit discussion, we came across Spectrum. Spectrum positions itself as “a platform for communities”, just what we had in mind.

Spectrum’s format for discussion is based on a question and comment system similar to GitHub issues. The questions are split up based on channels; e.g. feature requests or community help. This system makes it easy for someone to pick the channel they want, ask a question and get a timely response. On the homepage for our CameraKit group, there’s a helpful search feature next to different sortings of the questions. One can see the latest questions or what’s trending on CameraKit.

Spectrum is also easy to join and brings useful member management, analytics along with flexible team and administrator settings. We also have the ability to integrate Spectrum directly into our website.

Spectrum is still not perfect. Its a relatively new company, and we have occasionally encountered bugs and stability issues on their site. The website can also be confusing to navigate on first glance.

However, spectrum was recently acquired by GitHub! This gives us hope that the Spectrum will only grow in popularity and continue to be updated for the foreseeable future.

Pros:

  1. Easy to join
  2. Helpful management tools
  3. Robust search, and indexed online
  4. Strong backing

Cons:

  1. Still a young company: some bugs and stability issues
  2. Interface can be confusing to navigate

The Winner — Spectrum!

We are fond of our new home on Spectrum. With Spectrum’s acquisition by GitHub, no doubt these issues will be ironed out and the system improved in the future. We much prefer the ease of management Spectrum provides over the discussion focused style of Slack.

So if you haven’t already check us out on Spectrum. Leave a question or comment and we’ll be sure to get back to you!

Thanks for reading and we’ll see you around.


An Open Source Community: How We Came To Use Spectrum was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

CameraKit Release v0.13.4

Wed Jan 09 2019

While we are building video support in CameraKit v1.0.0, we will continue to maintain v0.13.X as the latest CameraKit version with video integration.

This latest release brings a few bug fixes and build improvements. You can see the full list of commits on our GitHub pull request. To view documentation, head over to camerakit.io/docs.

Here are the highlights.

  • Lower minimum SDK version to 15
  • Fix orientation of captured image with the front camera
  • Revert back from AndroidX to Android support libraries

CameraKit relying on AndroidX forced developers to also use AndroidX if they included CameraKit in their applications. In an effort to leave developers with as much choice as possible, we moved CameraKit back to the standard android-support libraries. This will allow developers to use AndroidX or standard Android Support in their own applications.

As always, if you encounter a problem or have a request for a feature, drop us an issue on GitHub or a message on Spectrum!


CameraKit Release v0.13.4 was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

APK Inspector v0.2.0

Wed Jan 02 2019

Last week we launched APK Inspector, a command line tool to determine dependencies and permissions from an APK file. Today we’ve released version 0.2.0 bringing new features and updates!

In version 0.2.0 you can now output permissions and dependencies to a JSON or text file. The default output is JSON, but you can change that behavior with the --output-type command line argument.

Here are the rest of the v0.2.0 highlights, you can see the entire pull request on GitHub.

Features

  • Output permissions and dependencies to JSON or text file.
  • Update default console logging behavior

Bug Fixes

  • Better handling of user input to reduce errors

GitHub

  • Add issue and contributing templates

APK Inspector v0.2.0 was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

Finding Permissions and Dependencies in an APK

Thu Dec 27 2018

Dissecting an APK: Permissions and Dependencies

I work at CameraKit, an open source platform to provide a reliable and easy to use Camera implementation in any Android application. We were recently interested in testing an APK to see whether or not it used CameraKit. Going one step further we wanted to test if an APK requested camera permissions.

We weren’t able to find a tool like this after a quick few Google searches so we decided to make our own!

Here’s what we learned about APKs along the way.

The Approach

If you want to follow along with this article, you can download an APK from APKMirror.com and use it with all the tools below!

We first turned to the Android Studio APK inspector to see what exactly makes up an APK.

Android Studio APK Analyzer

There are a few different types of files; AndroidManifest.xml, assets, meta information, and .dex classes.

Looking into the AndroidManifest.xml file you see almost exactly what was written when the application was created: SDK and version information, and most importantly, permissions!

So that will provide the permissions, now what about dependencies? Selecting the classes.dex file expands to reveal something like this:

classes.dex

Dex files

.dex is the file extension of the byte code format read by the Android Runtime (ART). This runtime environment operates and runs the bytecode on Android devices. Dex files are not Java bytecode, but its own format with entirely different bytecode instructions. These files contain a translated version of all the code and classes of the application. Aside from the lib, classes.dex is the largest component of this APK.

Huzzah! Our package com.camerakit is there, along with all the other packages requested by the application. You can see things like Kotlin, Android Support and Java IO.

All that’s left to do is find a way to automate this process and extract those package names.

Automation

The goal of this project is to quickly analyze any APK. Opening the APK through Android Studio and manually searching the classes.dex is far from efficient.

Unzipping

After further investigation I learned that APKs are a specific type of zip-format archive file. APKs are based on the Java Archive (JAR) format that’s used to compress Java class files and resources. APKs are also signed with an SHA1 Digest and a certificate. Both of these components are contained in the META-INF directory.

With these special considerations, renaming the file to .zip and unzipping it with a standard unzip tool most likely will not work. But we tried it anyways.

The result looked promising:

unzip APK

But opening any of the files confirms our suspicion.

����������.�����������������������������(���4���L���j���������������������������4��Z�����������������������2��x��������(��l��������8������������\�������2��F��X���������������t�h�e�m�e����l�a�b�e�l����i�c�o�n����n�a�m�e���
�d�e�b�u�g�g�a�b�l�e���

Simply unzipping the package leaves the files encoded resulting in unreadable text. Another method is needed to unpack and decode the APK.

APKTool

From their GitHub:

A tool for reverse engineering 3rd party, closed, binary Android apps. It can decode resources to nearly original form and rebuild them after making some modifications. It also makes working with an app easier because of the project like file structure and automation of some repetitive tasks like building apk, etc.

APKTool does just what we wanted, unzips and decodes the APK turning the files into human readable text. Now opening the same APK with APKTool gives the following output.

APKTool output

The output includes an assets folder, and something called smali. We’ll get back to that in a second. AndroidManifest.xml is now readable and contains exactly what we saw from the Android Studio APK Analyzer.

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="28"
android:compileSdkVersionCodename="9" package="com.example.emerson.camerakittest" platformBuildVersionCode="1" platformBuildVersionName="1.0">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
...

Reading the permissions is as easy as loading AndroidManifest.xml and grabbing all of the <uses-permission> lines. The dependencies will take a tad more effort.

Smali

As you can see in the above screenshot, the smali and smali_classes2 folders contain the same packages we saw in the classes.dex of the Android Studio APK Analyzer. Wouldn’t you know it our com.camerakit package is right there!

What is smali? Smali is the product of running a disassembler on a .dex file. Smali is a human readable but maintains the procedural structure of the dex file format. The process of converting dex to smali is called “backsmaling” and is done with APKTool by way of this GitHub repository.

Here’s an example of a smali file.

.method public getFacing()I
.locals 1
.line 674
iget v0, p0, Lcom/camerakit/CameraKitView;->mFacing:I
return v0
.end method

If you compare it to the Java source code you can see the close resemblance for a simple function like getFacing().

@CameraKit.Facing
public int getFacing() {
return mFacing;
}

However the contents of the smali file are not important for this project. All we need is the names of the folders, formatted as com.camerakit. This can be achieved by traversing through the folder structure, saving the names of the above directories to create one final package name. The package name is made up of all the directories that came before the folder containing smali files, which is most often the final name of the package.

For example the structure:

Turns into:

androidx.versionedparcelable
com.camerakit

APK Inspector

With access to both the permissions and packages used by the application, we created a command line tool APK Inspector to wrap it all up.

The main function is to run APKTool on a specified APK to reveal AndroidManifest.xml as well as the smali folders. From here, APK Inspector searches through AndroidManifest.xml for permissions and outputs them to the console. Then our program recursively iterates over the smali folders, concatenating the folder names into package names.

There are some basic options for the tool that you can see on the README. One can output permissions only, dependencies, or search for a specific permission or dependency.

Future Improvement

This is only the first draft of the project and I’m looking to keep making improvements to increase the speed and functionality. We’re open to feedback and love to hear your ideas, but we plan to refine APK Inspector to our own needs as we go forward.

As we continue to development, keep your eye out for more blog posts on the topic of APKs, how to deconstruct them, and possibly even other application formats.

Thanks for reading!


Finding Permissions and Dependencies in an APK was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

CameraKit v0.13.3

Thu Dec 06 2018

With the latest beta version, v1.0.0-beta3.10 migrating to AndroidX and receiving dependency updates, we thought it fitting to add the same to v0.13.3.

Here’s what’s new in CameraKit v0.13.3.

AndroidX

Just like I wrote in our release for v1.0.0-beta3.10, AndroidX will continue updates for Android’s support library. This will help CameraKit stay fully functional on older devices.

Video Duration Limits

Video duration limit added to the video recorder to stop recording video after a set amount of time. Thanks to @lucianoiam in Github for the contribution.

Dependency Updates

v0.13.3 matches the updates to Gradle and Kotlin we made in beta3.10.

Check out all of our changes on the Pull Request.

As always, we love to hear from the community. Find us on Github or send a message on Spectrum!

Thank you for being a part of CameraKit!


CameraKit v0.13.3 was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

Our New CameraKit Documentation Site

Thu Nov 29 2018

We always are working to find ways to make CameraKit more accessible and simple to use, and in the past few months, this has represented a big focus for us. We are advocates of open source in every way; not only for its ability to create great communities but also foster faster, easier, and more accessible developer environment for previously untouched problems.

As one of our first steps in making CameraKit more usable, we are happy to share our entirely new documentation site, housed within the CameraKit website: https://camerakit.io/docs

CameraKit helps you add reliable camera to your app quickly. Our open source camera platform provides consistent capture results, service that scales, and endless camera possibilities.

It is important that our new docs accomplish a few key things, for us and for our community…

  • Housed in the same domain as our primary web presence; we weren’t fans of using docs.camerakit.io and wanted to have easy reach in how users access and utilize the CameraKit documentation.
  • Multiple version support for past, current, and future CameraKit releases; ability to quickly comprehend the differences, implementation changes, and available API calls of older and newer versions.
  • Gooood-lookin’; we love our brand and are enjoying growing it, so the docs need to match the same style and simplicity associated with the rest of the CameraKit brand.

Our goal is to continue to grow the community around CameraKit. It is a priority for us and updating our documentation is just one of many steps we have planned (and most importantly are actively working on) in making that goal realized.

We have more enhancements already in the pipeline for the documentation site, but we welcome any feedback on https://spectrum.chat/camerakit/ or via our contact form https://camerakit.io/contact.


Our New CameraKit Documentation Site was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

CameraKit v1.0.0-beta3.10

Wed Nov 28 2018

The CameraKit team is hard at work creating a stable 1.0.0 release of CameraKit-Android! In the mean time, we will push smaller updates to address issues and feature requests we’ve received from the community.

Here’s what’s new in beta3.10.

AndroidX

AndroidX is Android’s new support library. Like the support library it replaces, AndroidX brings backwards compatibility across Android releases. AndroidX will allow CameraKit to stay up to date with the latest support improvements.

Clear Listeners

We added methods to remove the common listeners CameraKit supports including Preview, Camera, and Error listeners.

Dependency Updates

Beta3.10 also brings CameraKit dependencies up to date like Gradle and Kotlin.

You can see all the changes for yourself on the Pull Request.

We’re always looking for your feedback! If there is a feature you want to see, or a bug you’ve encountered create a ticket on GitHub. Or if you’d rather reach out to the developers directly, send us a message on Spectrum.

Thank you for being a part of CameraKit!


CameraKit v1.0.0-beta3.10 was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

Building a NestJS API — A Peek Through My Search History

Wed Nov 07 2018

Building a NestJS API — A Peek Through My Search History

Recently, I was tasked with creating our API. I chose NestJS to experiment with since its tagline:

A progressive Node.js framework for building efficient, reliable and scalable server-side applications.

really jived with me. I was excited to tackle this problem and thought with my JavaScript background — learning a new library while also learning TypeScript couldn’t be that hard, could it? Well, 500+ searches and a pretty good API foundation later, NestJS has lived up to the excitement. This article takes you through my development hurdles and successes.

A selection of my searches will be displayed in the format: search🔎 as well as quick answers to some. Additionally, on the search itself, I’ve linked to specific articles or posts that solved those queries.

API requirements

  • Typescript, TypeORM, GraphQL Support
  • Basic Splash Page that shows ‘API Operational’ with CameraKit Logo/etc
  • User scheme to support sign-in, sign-up, portal access, and user settings

Doing Research

It starts with the nestjs🔎 search. One that I had used seven more times over the course of development, most assuredly to get to the main NestJS site — a great source of documentation and best practices. I quickly realized I needed to take a step back to see what NestJS does. nestjs explanation🔎landed me this great article from Auth0. The next search nestjs vs nextjs🔎 seems a bit out of place, but to make things a bit more confusing, the main CameraKit website began transitioning to NextJS for server-side rendered React; which, of course, has nothing in common with NestJS besides very similar pronunciation.

Constructing the Scaffold

I soon gained a bit of confidence as I started branching off to the beginning steps of making an API— nestjs user authentication🔎 which led me down the path of using nestjs passport🔎, and then getting a bit more serious with the keyword-shotgun approach scaffold nestjs typescript typeorm graphql🔎 — a surprisingly helpful search which pointed me towards this GitHub Repository. I will implement some of the ideas here, just to have them not work later, though, after an update changes the interfaces. I then realized I should include Linting; tslint airbnb rules🔎, tslint config json extend🔎, and tsconfig.json🔎 helped set up TsLint with my preferred Airbnb Config. This was not any harder than installing and adding a line in tslint.json.

Adding a Database

Apollo support was next on my todo list:

🔎
- scaffold tests typescript typeorm grapql
- apollo server express
-
nestjs grapql scaffold

Though I ran into what I thought was a problem with a package version Module has no exported member ‘graphiqlexpress’🔎. I solved this by adding @types/grpahql. Only after some confusion: Removing carrots from dependencies🔎, What are carrots in package.json🔎.

After adding TypeORM (with the help of the docs), and deciding to use PostgreSQL as the database, I was ready to start writing some code.

🔎
-
add typeorm to nestjs
- best db to use with typeorm
- what database to use with typeorm
- typeorm and mongodb
- set up postgresql server on windows

Making the Index Page

I like starting with a splash page for the API to have a quick and dirty way to confirm requests are being served. This involved getting the file system

🔎
-
nestjs index example
- import path

- favicon

Including the favicon

🔎
- favicon

- favicon include in site
- Nestjs fastify “favicon”

As well as getting the image and font right

🔎
-
Roboto text
- font shorthand
- vertically align text in div
“CameraKit API Operational” on the index page

“nest can’t resolve dependencies of the”🔎

This search, and similar phrases, came up multiple times while developing with NestJS. An error might look something like:

[ExceptionHandler] Nest can't resolve dependencies of the UserController (UserService, ?). Please make sure that the argument at index [1] is available in the current context.

and I did not know where to look at first. I thought there was something I didn’t know about nestjs interface🔎 or typescript interface🔎, but there were some helpful clues. First, I looked inside the user.controller, and realized that (UserService, ?) points towards its constructor:

You can see NestJS knows about the UserService, and even though I believed I imported the SubscriptionService

nestjs imports exports providers🔎 showed me it both needs to be exported from subscription.module

As well as imported from the user.module

Using Different Development Environments

Because I develop on a Windows computer and Mac laptop, programs and services outside of the great NPM need to be installed: install postgres mac🔎, debugged: invalid active developer path🔎 and set up: create role postgresql🔎 postgresql mac service cli🔎 default postgres password🔎 create user postgres🔎. After getting back up to speed on the Mac side I begin implementing user registration and login. nest authentication login api🔎 and nestjs authentication🔎 kept pointing me towards nestjs/passport as well as the authentication technique in the NestJS docs. I eventually went with their “best practice”, and decided to follow the JWT approach.

🔎
- jwt passport persistent sessions
- express session
- nestjs passport session
- passport session
- passport jwt session
-
debugging nestjs
- auto attach vs option

Out of those searches, I realized I did not want to use express session as well as learning how to debug from here. For Visual Studio Code users turn on Auto Attach:

Visual Studio Code settings — search for “auto attach” and flip it on

and create nodemon.jsonwhich runs with nodemon.

Adding custom Configuration and Security

A few searches later,

🔎
- what passport strategy to use for logins local vs jwt
-
what’s the point of jwt
- saving jwt in local storage
- nestjs middleware cookie session login authentication
- passport extend strategy
- nestjs guard passport
-
use guards nestjs

I had the API hooked up to the web client in what I thought was a working state. I realized later that the nice comments in the example GitHub repository would need to be followed and implemented. After some worrying: authentication with jwt secure🔎 jwt brute force🔎 generate good jwt secret🔎 I needed a place to store my newly generated secret . I turned to dotenv🔎 to handle configuration files, and of course had to search how to name something starting with a dot in finder🔎. I started off with using purely environment variables and accessing them within the code from process.env.ENVIRONMENT_VARIABLE, but soon after nestjs configuration documentation🔎, I found my way back to the NestJS documentation which suggests using joi npm🔎 for validation. I followed the advanced configuration and made a global module nestjs global modules🔎. To round out my “security audit” I read and implemented nestjs force ssl🔎 for production

After quite a few searches

🔎
- express-sslify nestjs
- ssl “nestjs”
- nestjs redirect https
- res.redirect is not a function express-sslify

- 301 moved permanently from disk cache
- redirected you too many times https express

began to add CSRF protection csurf🔎 until I decided it was unnecessary at this time.

Deploying to Heroku

The next step was deployment to Heroku. Of course it did not work on the first try. I fixed bcrypt failing heroku🔎 by installing a new version, same with ts-node not found🔎, and an error that stumped me for a while — web process failed to bind to $PORT within 60 seconds of launch wait longer🔎. I originally thought I might need more time, but I actually needed to dynamically set the port according to the environment variable that Heroku assigns. When that still did not fix the problem app.listen string or number🔎 nestjs heroku port🔎 nestjs heroku deploy🔎 showed me the host was required to be set to 0.0.0.0.

I was then back to errors that I had seen before! This time concerning the environment variables. I was confused how the variables worked on Heroku, and realized after a bit of searching:

🔎
-
heroku dotenv
- push file to heroku
- put dotenv file in Heroku
-
“Dotenv” “heroku” site:stackoverflow.com
- dotenv parse current process env variables
- “Get all” environment variables dotenv

dotenv does not work with Heroku because the .envfile should never be committed. This is for good reason since your secrets would not be secret. Therefore, I solved the problem by either using the file (if found) or checking for environment variables that are already set and then validating them.

🔎
- get keys from object into different object specific
- get variables out of process.env
- assign specific object properties to new object
-
reduce mdn

With that done, more errors came up that looked like a typescript compilation problem, but with weird errors like cannot find global type ‘Boolean’.

🔎
-
‘AsyncIterator’. Do you need to change your target library?
- cannot find global type ‘Boolean’.
- cannot find name ‘Blob’
-
invalid module name in augmentation. Module ‘graphql/type/definition’
- unexpected token { import
-
tsc not converting imports

Almost everyone pointed towards fixes through tsconfig.json, yet suggestions to change the lib to X would remove Y error, but add Z error. I ended up with a tsconfig.jsonthat worked, but unfortunately I could not tell you why.

Still, TypeORM was throwing errors, and it was at this time I realized the TypeORM entities

🔎
-
no repository for “contact” was found
- typeorm entities
-
looks like this entity is not registered in current “default” connection

were correctly found during development in the /src directory, but since production moves the files to the/dist directory, the entities were not correctly found. I changed where TypeORM looks for the entity files by changing src/**/*.entity.tsto dist/**/*.entity.js.

Conclusion

To great relief, the server successfully deployed and started serving requests. I have since gone on to add more functionality as well as run into more problems, but that’s development! Thanks for reading, and if you’re interested: a full list of my searches!

CameraKit helps implement reliable Android camera into your mobile app easily. Open-source, performant, and optimized for tackling the complex Camera APIs on Android.


Building a NestJS API — A Peek Through My Search History was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

BlurKit Release v1.1.0

Thu Nov 01 2018

*chanting* BlurKit BlurKit BlurKit!

Here’s the skinny on the latest release.

Removed Kotlin

In the previous release we added Kotlin to our library, but we’ve since changed philosophy. Kotlin introduces a large dependency. Requiring our users to include such a dependency in their application is a lot to ask. Going forward we are going to stick to Java as our Android language of choice.

Transparency Control

Up until now there was no reliable way to adjust the transparency of the blur applied through BlurKit. We’ve added an XML attribute and Java call to set the alpha value of the blur.

  • XML: blk_alpha
  • Java: setAlpha(float alpha)

There’s a smattering of other minor changes you can see for yourself on the Pull Request.

If you found a bug or have a request for a feature, create an issue on GitHub. Or if you’d rather reach out to the developers directly send us a message on Spectrum.

Thanks for using BlurKit!


BlurKit Release v1.1.0 was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more