Skip to content

fix(adhoc-sweep-fixes): 40 review findings across 40 files - #123

Draft
flamingo[bot] wants to merge 40 commits into
mainfrom
ai-fix/adhoc-sweep-fixes-27666cf7-f6d23861
Draft

fix(adhoc-sweep-fixes): 40 review findings across 40 files#123
flamingo[bot] wants to merge 40 commits into
mainfrom
ai-fix/adhoc-sweep-fixes-27666cf7-f6d23861

Conversation

@flamingo

@flamingo flamingo Bot commented Aug 24, 2026

Copy link
Copy Markdown

Closes 40 review findings across 40 files.

Draft — this is a starting point, not a finished change. The fix required judgment, so read it before trusting it.

# Fix confidence Finding Location
1 🟢 90 high ActivityItem silently swallows Date parse errors without any recovery signal frontend/components/ActivityItem/ActivityItem.tsx:92
2 🟢 90 high Hardcoded input id="upload-file" duplicated across FileUploader instances causes DOM id collisions frontend/components/FileUploader/FileUploader.tsx:172
3 🟡 75 medium onInputOpen's setInterval polling for '.Select-menu-outer' never has an explicit unmount guard tied to component unmount frontend/components/forms/fields/SelectTargetsDropdown/SelectTargetsDropdown.jsx:79
4 🟢 95 high getOptions is exported but EditTeamsAbmModal component duplicates the same filter/map logic inline via useMemo instead of calling it frontend/pages/admin/IntegrationsPage/cards/MdmSettings/AppleBusinessManagerPage/components/EditTeamsAbmModal/EditTeamsAbmModal.tsx:100
5 🟡 75 medium EditUserPage teams diff logic can never clear a user's last team assignment frontend/pages/admin/ManageUsersPage/EditUserPage/EditUserPage.tsx:136
6 🟢 90 high OSUpdates redirects non-admin users using router.replace without halting render, causing extra render of restricted content frontend/pages/ManageControlsPage/OSUpdates/OSUpdates.tsx:104
7 🟢 92 high useMemo dependency array omits router and teamIdForApi, risking stale table config frontend/pages/SoftwarePage/components/tables/SoftwareVulnerabilitiesTable/SoftwareVulnerabilitiesTable.tsx:106
8 🟢 90 high getDeviceVppCommandResultHandler URL bypasses baseUrl() helper used everywhere else in the file frontend/test/handlers/device-handler.ts:100
9 🟡 75 medium software_install_scripts.ts and software_uninstall_scripts.ts diverge on supported extension sets without shared source frontend/utilities/software_uninstall_scripts.ts:18
10 🟢 90 high kiCaCertificate and kiCertificate constants are duplicate values, defeating differentiation orbit/pkg/cryptoinfo/info.go:20
11 🟢 90 high GetProcessesByName stops after first prefix match instead of collecting all matching processes orbit/pkg/platform/platform_notwindows.go:74
12 🟡 85 medium convertBool helper duplicated verbatim across VolumesGenerate/PhysicalStoresGenerate could be reused, but the real issue is unused ctx parameter orbit/pkg/table/diskutil/apfs/apfs_darwin.go:78
13 🟡 85 medium satisfiesConstraints compares uid as string, giving incorrect ordering for multi-digit uids orbit/pkg/table/tcc_access/tcc_access.go:178
14 🔴 40 low — review closely Lock-wait goroutine leaks when acquisition times out server/cron/calendar_cron.go:316
15 🟢 95 high policyID is captured from the teams INSERT result, not the policies INSERT result server/datastore/mysql/migrations/tables/20220524102918_CleanupOrphanedPolicyMemberships_test.go:18
16 🟢 90 high Migration file name/date mismatch and reused function-name suffix diverges from filename timestamp server/datastore/mysql/migrations/tables/20241210140021_AddErrorsToCronStatsTable.go:8
17 🔴 40 low — review closely QueryByName error message says 'Report' instead of 'Query' on not-found path (pre-existing bug, but also present in SaveQuery) server/datastore/mysql/queries.go:218
18 🟢 90 high Type assertion val.(*mdm.BootstrapToken) will panic if execStores returns nil interface on error server/mdm/nanomdm/storage/allmulti/bstoken.go:14
19 🟡 65 medium labelRef helper takes new(id) which does not compile as written (invalid use of built-in new) server/mdm/reconcile/reconcile_test.go:40
20 🔴 45 low — review closely HasCN in bolt depot has TODO stubs for allowTime and revocation, silently ignoring renewal-window and revocation checks server/mdm/scep/depot/bolt/depot.go:178
21 🔴 35 low — review closely testUsers map and createTestUsers helper duplicated verbatim between svctest and service test package server/service/testing_utils_test.go:254
22 🟡 85 medium GetIssueProjectStatuses silently masks all failure modes as 'not present' tools/github-manage/pkg/ghapi/milestone.go:166
23 🟡 75 medium Android enterprise creation swallows distinct GCP error types into a single generic invalidEnterpriseToken exit for all 400s website/api/controllers/android-proxy/create-android-enterprise.js:152
24 🟡 75 medium Google API deletion errors silently swallowed with an empty catch website/api/controllers/android-proxy/delete-one-android-enterprise.js:83
25 🟡 70 medium get-stripe-checkout-session-url.js trusts quoteRecord.numberOfHosts without verifying it belongs to the requesting user website/api/controllers/customers/get-stripe-checkout-session-url.js:33
26 🟢 98 high Typo 'enollment' in delete bootstrap package modal copy frontend/pages/ManageControlsPage/SetupExperience/cards/BootstrapPackage/components/DeleteBootstrapPackageModal/DeleteBootstrapPackageModal.tsx:27
27 🟢 98 high Log message misspells 'workflors' for 'workflows' in uninstall script header comment it-and-security/lib/linux/scripts/uninstall-fleetd-linux.sh:2
28 🟢 95 high Package doc comment typo in fleetdbase package declaration pkg/fleetdbase/fleetd_base.go:1
29 🟢 95 high Duplicated/redundant comment line in VPP token teams migration server/datastore/mysql/migrations/tables/20240829170023_CreateVPPTokenTeamsJoinTable.go:13
30 🟢 98 high Package doc comment typo: 'Pacakge' instead of 'Package' server/mdm/nanomdm/service/nanomdm/service.go:1
31 🟢 95 high Grammatical/word error in conditional-access blocking-policy banner copy frontend/pages/hosts/details/cards/Policies/HostPoliciesTable/PolicyFailingCount/PolicyFailingCount.tsx:46
32 🟢 95 high Misleading comment 'GetIssues fetches issues' on GetUserName function tools/github-manage/pkg/ghapi/user.go:20
33 🟢 95 high Misspelled prop name 'untegrationSubmitData' in IIntegrationFormProps.onSubmit signature frontend/pages/admin/IntegrationsPage/cards/Integrations/components/IntegrationForm/IntegrationForm.tsx:21
34 🟢 95 high Redundant duplicate column in GROUP BY clause server/datastore/mysql/migrations/tables/20251028140000_CreateTableOSVersionVulnerabilities.go:68
35 🟢 98 high Leftover console.log(el) in production page component website/assets/js/pages/articles/basic-comparison.page.js:27
36 🟢 95 high Misspelled tenant name in warning log message website/scripts/send-entra-heartbeat-requests.js:82
37 🟢 95 high MacOfficeReleaseNotes error check duplicates MSRCBulletins call instead of its own method in fs_test.go server/vulnerabilities/io/fs_test.go:25
38 🟢 95 high Duplicate test case name in TestJobs table hides the second subtest under an identical -run selector server/datastore/mysql/jobs_test.go:19
39 🟢 95 high Migration function doc comment references wrong migration ID (copy-paste artifact) server/datastore/mysql/migrations/tables/20260518194422_AddEncodingTypeToHostSCDData.go:12
40 🔴 40 low — review closely Misspelled log message field 'retreiving' in mdm_cert.go server/mdm/nanomdm/http/mdm/mdm_cert.go:214

What changed — and what was deliberately left — is explained per finding as inline review comments on the lines each finding touched.


Run: https://product-hub.flamingo.so/admin/code-review
Run id: f6d23861-693f-45a1-b5b3-570aa3bc9ea7

Merging this PR is recorded as acceptance of the rule that produced it;
closing it unmerged is recorded as rejection. Both feed rule health, so
closing a wrong suggestion is useful rather than merely tidy.

flamingo Bot added 30 commits August 24, 2026 06:41

@flamingo flamingo Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 What this fix changed, finding by finding

40 finding(s) fixed in this draft — 40 explained inline on the diff; 5 low-confidence hunk(s) need close review before merging.

@@ -91,11 +91,10 @@ const ActivityItem = ({
? addGravatarUrlToResource({ email: actor_email })
: { gravatar_url: undefined };

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 ActivityItem silently swallows Date parse errors without any recovery signal

In ActivityItem, replaced the dead try/catch around new Date(activity.created_at) with a direct construction followed by an isNaN(activityCreatedAt.getTime()) check that falls back to new Date() when the parsed date is invalid. This matches the finding's suggested fix and removes the false sense of safety from the unreachable catch block.

🤖 Prompt for AI agents
In frontend/components/ActivityItem/ActivityItem.tsx around line 92, review and complete this code-review fix: ActivityItem silently swallows Date parse errors without any recovery signal.
What the draft fix changed: In `ActivityItem`, replaced the dead try/catch around `new Date(activity.created_at)` with a direct construction followed by an `isNaN(activityCreatedAt.getTime())` check that falls back to `new Date()` when the parsed date is invalid. This matches the finding's suggested fix and removes the false sense of safety from the unreachable catch block.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 90 high — react 👍/👎 to teach the reviewer

Comment on lines 177 to 183
// If we want to actual do file uploading, wrap in a label that
// references the hidden file input. Otherwise just use a span.
if (!onButtonClick) {
buttonMarkup = <label htmlFor="upload-file">{buttonMarkup}</label>;
buttonMarkup = <label htmlFor={fileInputId}>{buttonMarkup}</label>;
} else {
buttonMarkup = <span>{buttonMarkup}</span>;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Hardcoded input id="upload-file" duplicated across FileUploader instances causes DOM id collisions

In FileUploader, added const fileInputId = useId(); and replaced the hardcoded literal "upload-file" with fileInputId on both the <label htmlFor={fileInputId}> (in renderUploadButton) and the hidden <input id={fileInputId}> (in renderFileUploader), ensuring each mounted instance gets a unique DOM id and label click delegation works correctly for multiple instances on the same page.

🤖 Prompt for AI agents
In frontend/components/FileUploader/FileUploader.tsx around line 172, review and complete this code-review fix: Hardcoded input id="upload-file" duplicated across FileUploader instances causes DOM id collisions.
What the draft fix changed: In `FileUploader`, added `const fileInputId = useId();` and replaced the hardcoded literal `"upload-file"` with `fileInputId` on both the `<label htmlFor={fileInputId}>` (in `renderUploadButton`) and the hidden `<input id={fileInputId}>` (in `renderFileUploader`), ensuring each mounted instance gets a unique DOM id and label click delegation works correctly for multiple instances on the same page.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 90 high — react 👍/👎 to teach the reviewer

Comment on lines 89 to 108
const { document } = global;
const { wrapperHeight } = this;

const lookForOuterMenu = setInterval(() => {
this.lookForOuterMenu = setInterval(() => {
if (!this.mounted) {
clearInterval(this.lookForOuterMenu);
return;
}

if (document.querySelectorAll(".Select-menu-outer")) {
clearInterval(lookForOuterMenu);
clearInterval(this.lookForOuterMenu);
const coreWrapper = document.querySelector(".core-wrapper");

if (!coreWrapper) {
return;
}

const currentWrapperHeight = coreWrapper.scrollHeight;
if (wrapperHeight < currentWrapperHeight) {
coreWrapper.style.height = `${

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 onInputOpen's setInterval polling for '.Select-menu-outer' never has an explicit unmount guard tied to component unmount

In onInputOpen, the interval id is now stored on this.lookForOuterMenu (instead of a local const) and componentWillUnmount now calls clearInterval(this.lookForOuterMenu) to guarantee the poll stops on unmount. Additionally, the interval callback now checks this.mounted first (clearing and returning early if unmounted) and guards coreWrapper being null before dereferencing .scrollHeight, matching the mounted-check pattern used elsewhere in the file (e.g. fetchTargets). This directly addresses the missing unmount guard and the potential throw from document.querySelector('.core-wrapper') returning null after unmount. The pre-existing querySelectorAll always-truthy logic bug was left unchanged since fixing it was outside the scope of this finding.

🤖 Prompt for AI agents
In frontend/components/forms/fields/SelectTargetsDropdown/SelectTargetsDropdown.jsx around line 79, review and complete this code-review fix: onInputOpen's setInterval polling for '.Select-menu-outer' never has an explicit unmount guard tied to component unmount.
What the draft fix changed: In `onInputOpen`, the interval id is now stored on `this.lookForOuterMenu` (instead of a local const) and `componentWillUnmount` now calls `clearInterval(this.lookForOuterMenu)` to guarantee the poll stops on unmount. Additionally, the interval callback now checks `this.mounted` first (clearing and returning early if unmounted) and guards `coreWrapper` being null before dereferencing `.scrollHeight`, matching the mounted-check pattern used elsewhere in the file (e.g. `fetchTargets`). This directly addresses the missing unmount guard and the potential throw from `document.querySelector('.core-wrapper')` returning null after unmount. The pre-existing `querySelectorAll` always-truthy logic bug was left unchanged since fixing it was outside the scope of this finding.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 75 medium — react 👍/👎 to teach the reviewer

return availableTeams
?.filter((t) => t.name !== "All fleets")
.map((t) => ({
value: t.name,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 getOptions is exported but EditTeamsAbmModal component duplicates the same filter/map logic inline via useMemo instead of calling it

In EditTeamsAbmModal component, replaced the inline useMemo body that duplicated the filter/map logic with a direct call to the exported getOptions(availableTeams) function, keeping the same [availableTeams] dependency array. This removes the duplicated logic while preserving identical behavior.

🤖 Prompt for AI agents
In frontend/pages/admin/IntegrationsPage/cards/MdmSettings/AppleBusinessManagerPage/components/EditTeamsAbmModal/EditTeamsAbmModal.tsx around line 100, review and complete this code-review fix: getOptions is exported but EditTeamsAbmModal component duplicates the same filter/map logic inline via useMemo instead of calling it.
What the draft fix changed: In `EditTeamsAbmModal` component, replaced the inline `useMemo` body that duplicated the filter/map logic with a direct call to the exported `getOptions(availableTeams)` function, keeping the same `[availableTeams]` dependency array. This removes the duplicated logic while preserving identical behavior.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 95 high — react 👍/👎 to teach the reviewer

Comment on lines 128 to 134
requestData.mfa_enabled = formData.mfa_enabled;
if (formData.global_role !== entityData.global_role)
requestData.global_role = formData.global_role;
if (formData.teams && formData.teams.length > 0)
requestData.teams = formData.teams;
if (formData.teams) requestData.teams = formData.teams;
if (formData.new_password) requestData.new_password = formData.new_password;

let successMessage = `Successfully edited ${formData.name}`;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 EditUserPage teams diff logic can never clear a user's last team assignment

In handleHumanUserSubmit in EditUserPage.tsx, changed the condition if (formData.teams && formData.teams.length > 0) requestData.teams = formData.teams; to if (formData.teams) requestData.teams = formData.teams;. This allows an empty array (all teams removed) to be included in the request payload, so the backend receives the cleared team list instead of silently keeping the old assignments, while still omitting the field when formData.teams is undefined/null (e.g., not applicable for this user). Risk: if formData.teams defaults to an empty array rather than undefined for users/forms where teams aren't managed, this could now send an unintended empty teams update; verifying the UserForm's default/initial value for teams would give full confidence.

🤖 Prompt for AI agents
In frontend/pages/admin/ManageUsersPage/EditUserPage/EditUserPage.tsx around line 136, review and complete this code-review fix: EditUserPage teams diff logic can never clear a user's last team assignment.
What the draft fix changed: In `handleHumanUserSubmit` in EditUserPage.tsx, changed the condition `if (formData.teams && formData.teams.length > 0) requestData.teams = formData.teams;` to `if (formData.teams) requestData.teams = formData.teams;`. This allows an empty array (all teams removed) to be included in the request payload, so the backend receives the cleared team list instead of silently keeping the old assignments, while still omitting the field when `formData.teams` is `undefined`/`null` (e.g., not applicable for this user). Risk: if `formData.teams` defaults to an empty array rather than `undefined` for users/forms where teams aren't managed, this could now send an unintended empty teams update; verifying the UserForm's default/initial value for `teams` would give full confidence.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 75 medium — react 👍/👎 to teach the reviewer

@@ -81,7 +81,7 @@ module.exports = {
} else {
// If an error was logged for a entra tenant, log the error, and increment the numberOfLoggedErrors

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🔵 Misspelled tenant name in warning log message

Fixed the typo 'Microsfot' to 'Microsoft' in the sails.log.warn call inside the fn function's error-reporting loop at the end of the script, where warnings are logged for failed Entra tenant heartbeat requests.

🤖 Prompt for AI agents
In website/scripts/send-entra-heartbeat-requests.js around line 82, review and complete this code-review fix: Misspelled tenant name in warning log message.
What the draft fix changed: Fixed the typo 'Microsfot' to 'Microsoft' in the sails.log.warn call inside the fn function's error-reporting loop at the end of the script, where warnings are logged for failed Entra tenant heartbeat requests.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 95 high — react 👍/👎 to teach the reviewer

@@ -23,7 +23,7 @@ func TestFSClient(t *testing.T) {
t.Run("MacOfficeReleaseNotes", func(t *testing.T) {
t.Run("directory does not exists", func(t *testing.T) {
sut := NewFSClient("asdf")

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🔵 MacOfficeReleaseNotes error check duplicates MSRCBulletins call instead of its own method in fs_test.go

In TestFSClient's "MacOfficeReleaseNotes" > "directory does not exists" subtest, changed sut.MSRCBulletins() to sut.MacOfficeReleaseNotes() so the test correctly exercises the MacOfficeReleaseNotes error path instead of duplicating the MSRCBulletins test.

🤖 Prompt for AI agents
In server/vulnerabilities/io/fs_test.go around line 25, review and complete this code-review fix: MacOfficeReleaseNotes error check duplicates MSRCBulletins call instead of its own method in fs_test.go.
What the draft fix changed: In TestFSClient's "MacOfficeReleaseNotes" > "directory does not exists" subtest, changed `sut.MSRCBulletins()` to `sut.MacOfficeReleaseNotes()` so the test correctly exercises the MacOfficeReleaseNotes error path instead of duplicating the MSRCBulletins test.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 95 high — react 👍/👎 to teach the reviewer

Comment on lines 21 to 27
fn func(t *testing.T, ds *Datastore)
}{
{"QueueAndProcessJobs", testQueueAndProcessJobs},
{"QueueAndProcessJobs", testQueueAndProcessFilteredJobs},
{"QueueAndProcessFilteredJobs", testQueueAndProcessFilteredJobs},
{"CleanupWorkerJobs", testCleanupWorkerJobs},
}
for _, c := range cases {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🔵 Duplicate test case name in TestJobs table hides the second subtest under an identical -run selector

In TestJobs, renamed the second cases-slice entry's name field from "QueueAndProcessJobs" to "QueueAndProcessFilteredJobs" (which maps to testQueueAndProcessFilteredJobs) so each t.Run subtest has a unique, descriptive name and can be selected independently via go test -run.

🤖 Prompt for AI agents
In server/datastore/mysql/jobs_test.go around line 19, review and complete this code-review fix: Duplicate test case name in TestJobs table hides the second subtest under an identical -run selector.
What the draft fix changed: In TestJobs, renamed the second cases-slice entry's name field from "QueueAndProcessJobs" to "QueueAndProcessFilteredJobs" (which maps to testQueueAndProcessFilteredJobs) so each t.Run subtest has a unique, descriptive name and can be selected independently via `go test -run`.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 95 high — react 👍/👎 to teach the reviewer

MigrationClient.AddMigration(Up_20260518194422, Down_20260518194422)
}

// Up_20260514220719 adds the encoding_type column that discriminates between

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🔵 Migration function doc comment references wrong migration ID (copy-paste artifact)

Changed the doc comment above Up_20260518194422 from "Up_20260514220719 adds the encoding_type column..." to "Up_20260518194422 adds the encoding_type column...", correcting the copy-paste artifact so the comment references the correct migration function/ID it documents.

🤖 Prompt for AI agents
In server/datastore/mysql/migrations/tables/20260518194422_AddEncodingTypeToHostSCDData.go around line 12, review and complete this code-review fix: Migration function doc comment references wrong migration ID (copy-paste artifact).
What the draft fix changed: Changed the doc comment above Up_20260518194422 from "Up_20260514220719 adds the encoding_type column..." to "Up_20260518194422 adds the encoding_type column...", correcting the copy-paste artifact so the comment references the correct migration function/ID it documents.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 95 high — react 👍/👎 to teach the reviewer

Comment on lines 240 to 246
id, err := store.EnrollmentFromHash(r.Context(), hasher(cert))
if err != nil {
ctxlog.Logger(r.Context(), logger).Info(
"msg", "retreiving enrollment from hash",
"msg", "retrieving enrollment from hash",
"err", err,
)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🔵 Misspelled log message field 'retreiving' in mdm_cert.go

Fixed the typo 'retreiving' to 'retrieving' in the log message string within the CertWithEnrollmentIDMiddleware function's error handling branch (around the store.EnrollmentFromHash call), matching exactly the finding's evidence and location.

(Automatically downgraded: no change in this fix lands near this finding's line — verify whether it was actually addressed.)

🤖 Prompt for AI agents
In server/mdm/nanomdm/http/mdm/mdm_cert.go around line 214, review and complete this code-review fix: Misspelled log message field 'retreiving' in mdm_cert.go.
What the draft fix changed: Fixed the typo 'retreiving' to 'retrieving' in the log message string within the CertWithEnrollmentIDMiddleware function's error handling branch (around the `store.EnrollmentFromHash` call), matching exactly the finding's evidence and location.

_(Automatically downgraded: no change in this fix lands near this finding's line — verify whether it was actually addressed.)_
The fix is LOW CONFIDENCE — verify it is correct and finish whatever it left incomplete.

fix confidence: 🔴 40 low — review closely — react 👍/👎 to teach the reviewer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants