playlist:edit saved the playlist without the raw option, so every title
was rebuilt from the API channel name and country instead of being
written back as read. For a stream whose channel is not in the database,
that becomes "undefined (undefined)". playlist:format, playlist:update
and playlist:test already save with { public: false, raw: true }.
playlist:validate decides which streams belong to the selected files by
comparing the raw command-line arguments with the paths returned by
Storage.list(). A path such as ./streams/us.m3u never matches
streams/us.m3u, so the file's own streams are put in the duplicate buffer
and every link is reported as already being in that same file.
Resolve the arguments with getStoragePath(), as playlist:format does.
- stream.updateWithIssue: 'Live 24/7: Yes' meant the stream IS 24/7, but it
was assigned straight to isNot247, inverting the label. A 'No' answer was
also ignored because the guard skipped falsy values.
- dataSet.getBoolean: an unanswered dropdown is stored as '' by
parseIssueBody, which getBoolean read as false. Treat it as undefined so
'no answer' means 'leave unchanged' instead of 'Not 24/7'.
- update.addStream: has() is true for an unanswered field, so it produced
isNot247 = true for issues that left the dropdown blank.
- generate: sortBy got five orders for four iteratees.
- 2_streams_edit.yml: restore the '~' reset option dropped from the quality
dropdown when the Label field was removed.
- stream.getLabels: use const to satisfy prefer-const.